package com.foo.designpattern.proxy.dynamicproxy1.jdkdynamicproxy1;

import junit.framework.TestCase;

import java.lang.reflect.Proxy;

/**
 * com.foo.designpattern.proxy.dynamicproxy1.jdkdynamicproxy1
 * Created with IntelliJ IDEA.
 * Created by jiang on 2016-04-29 21:11.
 *
 * @Description 测试类：jdk动态代理1
 * 代理模式的实现，主要有以下几个特点：
 * 1、真实对象和代理对象拥有共同的父类或者实现相同的接口，实现了相同的方法。
 * 2、代理对象引用或者包含真实对象的一个实例，该实例在代理对象中初始化，代理对象通过1中所述的方法来替代对真实对象的调用。
 * 3、客户端中不再实例化真实对象，完全通过代理对象来访问真实对象。
 * <p/>
 * Java中要创建一个代理对象，必须调用Proxy类的静态方法newProxyInstance，该方法的原型如下：
 * Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,  InvocationHandler h) throws IllegalArgumentException
 * 其中的参数解释：
 * loader，表示类加载器，对于不同来源（系统库或网络等）的类需要不同的类加载器来加载，这是Java安全模型的一部分。可以使用null来使用默认的加载器。
 * interfaces，表示接口或对象的数组，它就是前述代理对象和真实对象都必须共有的父类或者接口。
 * handler，表示调用处理器，它必须是实现了InvocationHandler接口的对象，其作用是定义代理对象中需要执行的具体操作。
 */

public class JDKDynamicProxy1TestCase extends TestCase {
    public void testJDKDynamicProxy1() {
        System.out.println("= = = = ↓↓↓代理模式：jdk动态代理，测试开始↓↓↓ = = = =");

        FilterHandler firstHandler = new FilterHandler("com.foo.designpattern.proxy.dynamicproxy1.jdkdynamicproxy1.FirstAction");
        // 动态创建代理对象，用于代理 FirstAction 类型的真实对象
        Action firstAction = (Action) Proxy.newProxyInstance(Action.class.getClassLoader(), new Class[]{Action.class}, firstHandler);

        FilterHandler secondHandler = new FilterHandler("com.foo.designpattern.proxy.dynamicproxy1.jdkdynamicproxy1.SecondAction");
        // 动态创建代理对象，用于代理 SecondAction 类型的真实对象
        Action secondAction = (Action) Proxy.newProxyInstance(Action.class.getClassLoader(), new Class[]{Action.class}, secondHandler);

        FilterHandler thirdHandler = new FilterHandler("com.foo.designpattern.proxy.dynamicproxy1.jdkdynamicproxy1.ThirdActionNot");
        // 动态创建代理对象，用于代理 ThirdActionNot 类型的真实对象
        Action thirdActionNot = (Action) Proxy.newProxyInstance(Action.class.getClassLoader(), new Class[]{Action.class}, thirdHandler);

        // 两个以Action为结尾的类，成功执行excute方法
        firstAction.excute();
        secondAction.excute();
        // 并非以Action为结尾的类，方法执行请求被驳回
        thirdActionNot.excute();

        System.out.println("= = = = ↑↑↑代理模式：jdk动态代理，测试结束↑↑↑ = = = =");
    }
}
